package app.socket.server;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import app.entity.IOTPBean;
import app.htby.utils.Code;
import app.htby.utils.IotpBodyUtils;

public class NIOServer implements Runnable {
	private int port;
	private Charset cs = Charset.forName("utf-8");
	private ByteBuffer sBuffer = ByteBuffer.allocate(1024 * 9);
	private ByteBuffer rBuffer = ByteBuffer.allocate(1024 * 9);
	private Map<String, SocketChannel> clientsMap = new HashMap<String, SocketChannel>();
	private Selector selector;

	public NIOServer(int port) {
		this.port = port;
		try {
			init();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private void init() throws IOException {
		// 打开ServerSocketChannel，用于监听客户端的连接，它是所有客户端连接的父管道
		ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
		// 设置连接为非阻塞模式
		serverSocketChannel.configureBlocking(false);
		// 绑定监听端口
		ServerSocket serverSocket = serverSocketChannel.socket();
		serverSocket.bind(new InetSocketAddress(port));
		// 创建Reactor线程，创建多路复用器并启动线程
		selector = Selector.open();
		serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);
		System.out.println("server start on port:" + port);
	}

	public void run() {
		while (true) {
			try {
				selector.select();
				Set<SelectionKey> selectionKeys = selector.selectedKeys();
				for (SelectionKey key : selectionKeys) {
					handle(key);
				}
				selectionKeys.clear();
			} catch (Exception e) {
				e.printStackTrace();
				break;
			}

		}
	}

	private void handle(SelectionKey selectionKey) throws IOException, InterruptedException {
		ServerSocketChannel server = null;
		SocketChannel client = null;
		String receiveText = null;
		int count = 0;
		if (selectionKey.isAcceptable()) {// 客户端请求连接事件
			System.out.println("isAcceptable");
			server = (ServerSocketChannel) selectionKey.channel();
			client = server.accept();
			// 判断client 是否为空
			if (client != null) {
				System.out.println("000");
				client.configureBlocking(false);
				client.register(selector, SelectionKey.OP_READ);
			}
		} else if (selectionKey.isReadable()) {// 获得了可读的事件
			System.out.println("isReadable");
			boolean failure = true;

			client = (SocketChannel) selectionKey.channel();
			rBuffer.clear();
			try {
				count = client.read(rBuffer);
				failure = false;
			} catch (Exception e) {
				System.out.println("断开连接");
//				e.printStackTrace();
			}

			if (count <= 0 || failure) {
				selectionKey.cancel(); // Some JDK implementations run into an infinite loop without this.
				System.out.println("客户端关闭");
			} else {
				IotpBodyUtils ibu = new IotpBodyUtils();
				rBuffer.clear();
				byte[] bytes = new byte[count];
//				bytes = new byte[rBuffer.remaining()];
				rBuffer.get(bytes, 0, bytes.length);
//				System.out.println("Array1:" + Arrays.toString(rBuffer.array()));
//				System.out.println("Array2:" + Arrays.toString(bytes));
				
				Code c = ibu.toIotpBean(bytes);
				System.out.println("code:"+c.toString());
				IOTPBean iotpBean = ibu.getIotpBean();
				
				receiveText = bytes.toString();
				System.out.println("服务器端收到数据：" + iotpBean.toString());
//				 写数据
				ByteBuffer outBuffer = ByteBuffer.wrap(bytes);
				client.write(outBuffer);// 将消息回送给客户端
			}

			
		}
	}


	public static void main(String[] args) throws InterruptedException {
		// 创建MyServer
		NIOServer server1 = new NIOServer(8888);
		// NIOServer server2 = new NIOServer(7777);
		new Thread(server1).start();
		// new Thread(server2).start();

	}
}